package zoltan.balog.run;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

import zoltan.balog.generator.IGenerator;
import zoltan.balog.result.IResult;
import zoltan.balog.solver.ISolver;

public class Runner {

	private static final String outFileName = "solution.txt";
	private static final String lineSeparator = System.getProperty("line.separator");
	
	private IGenerator generator;
	private ISolver solver;

	public void run() {
		int times = 1;
		Logger.getAnonymousLogger().log(Level.INFO, System.getProperty("line.separator") + "Start calculation " + times + " times...");
		long averageTime = 0;
		IResult result = null;
		
		for (int i = 0; i < times; i++) {
			long runningTime = System.currentTimeMillis();
			
			result = solver.solve(generator.generate());
			runningTime = System.currentTimeMillis() - runningTime;
			averageTime += runningTime;
			
			Logger.getAnonymousLogger().log(Level.INFO, "Solution has calculated in " + runningTime + " ms");
		}
		
		Logger.getAnonymousLogger().log(Level.INFO, lineSeparator 
				+ "-----------------------------" + lineSeparator
				+ "Solution has calculated in average " + averageTime / times + " ms");
		
		Logger.getAnonymousLogger().log(Level.INFO, "Optimum: " + result.getOptimum());
		logResultToFile(result);
	}

	private void logResultToFile(IResult result) {
		try {
			File file = new File(outFileName);
			FileWriter writer = new FileWriter(file, true);
			
			writer.write(lineSeparator);
			Logger.getAnonymousLogger().log(Level.INFO, "Logging solution to file " + file.getAbsolutePath());
			StringBuilder builder = new StringBuilder(result.toString());
			
			writer.write(lineSeparator);
			writer.write(builder.toString());
			writer.flush();
			writer.close();
		} catch (IOException e) {
			Logger.getAnonymousLogger().log(Level.WARNING, "An IOExcaption caught while logging solution to file! ", e);
		}
	}

	public void setGenerator(final IGenerator generator) {
		this.generator = generator;
	}

	public void setSolver(final ISolver solver) {
		this.solver = solver;
	}
}
